import 'dart:convert';
import 'dart:io';

import 'package:concierge/config/config.gen.dart';
import 'package:get/get.dart';

class LogOssService extends GetConnect {
  @override
  void onInit() {
    super.onInit();
    httpClient.timeout = const Duration(seconds: 30);
    httpClient.addRequestModifier<dynamic>((request) {
      if (request.url.host.contains('vertu.cn')) {
        request.headers['Authorization'] = 'Bearer ${yamlMap.oss.token}';
      }
      return request;
    });
  }

  // 专门为签名接口创建一个忽略证书验证的 HTTP 请求方法
  Future<Map<String, dynamic>?> _signWithInsecureClient(
    String url,
    Map<String, dynamic> body,
  ) async {
    final client = HttpClient();

    // 对所有 vertu.cn 域名忽略证书验证（包括正式环境和测试环境）
    client.badCertificateCallback = (cert, host, port) {
      return host.contains('vertu.cn');
    };

    try {
      final request = await client.postUrl(Uri.parse(url));

      // 设置请求头，确保正确的编码
      request.headers.set('Content-Type', 'application/json; charset=utf-8');
      request.headers.set('Authorization', 'Bearer ${yamlMap.oss.token}');

      // 写入请求体，使用 UTF-8 编码
      final jsonBody = jsonEncode(body);
      final utf8Body = utf8.encode(jsonBody);
      request.add(utf8Body);

      // 发送请求
      final response = await request.close();

      // 读取响应
      final responseBody = await response.transform(utf8.decoder).join();

      print('[Upload Log] Insecure client response: $responseBody');

      if (response.statusCode == 200) {
        return jsonDecode(responseBody);
      } else {
        print(
          '[Upload Log] Insecure client request failed with status: ${response.statusCode}',
        );
        return null;
      }
    } catch (e) {
      print('[Upload Log] Insecure client request error: $e');
      return null;
    } finally {
      client.close();
    }
  }

  Future<Response> _sign(String name) async {
    // 直接使用忽略证书验证的方式请求签名接口
    final responseData = await _signWithInsecureClient(
      yamlMap.oss.sign_url
          .firstWhere((m) => m.type == yamlMap.oss.current_env)
          .url,
      {
        'dir': name.startsWith('/') ? name.substring(1) : name,
        'bucket': 'concierge-logs',
        'callback_url': '',
      },
    );
    if (responseData != null) {
      return Response(body: responseData, statusCode: 200, statusText: 'OK');
    } else {
      return Response(
        body: null,
        statusCode: 500,
        statusText: 'Certificate verification failed',
      );
    }
  }

  Future<String> upload(String dir, File file) async {
    print('[Upload Log] Starting upload for dir: $dir');
    String filename = file.path.split('/').last;
    final res = await _sign('$dir/$filename');
    if (res.body == null || res.hasError || res.body['code'] != 200) {
      print(
        '[Upload Log] Sign request failed. Status: ${res.statusCode} ${res.statusText}, Body: ${res.bodyString}',
      );
      return '';
    }

    print(
      '[Upload Log] Sign request successful. Response: ${jsonEncode(res.body)}',
    );

    final signData = res.body['data'];
    if (signData == null ||
        signData['code'] != 200 ||
        signData['data'] == null) {
      print('[Upload Log] Sign response data is invalid.');
      return '';
    }

    final ossData = signData['data'];

    final formData = FormData({});
    Map<String, String> fieldsMap = {
      'key': ossData['dir'],
      'OSSAccessKeyId': ossData['access_id'],
      'policy': ossData['policy'],
      'signature': ossData['signature'],
      'expire': ossData['expire'].toString(),
    };
    if (ossData.containsKey('callback') &&
        ossData['callback'] != null &&
        ossData['callback'].isNotEmpty) {
      fieldsMap['callback'] = ossData['callback'];
    }

    formData.fields.addAll(fieldsMap.entries);
    formData.files.add(
      MapEntry('file', MultipartFile(file, filename: filename)),
    );

    String url = ossData['host'];
    print('[Upload Log] Uploading to OSS: $url');
    print('[Upload Log] FormData fields: $fieldsMap');
    print('[Upload Log] FormData file: $filename');
    final result = await post(url, formData);
    if (result.isOk) {
      print('[Upload Log] OSS Upload successful. Status: ${result.statusCode}');
      return '${ossData['host']}${ossData['dir']}';
    } else {
      print(
        '[Upload Log] OSS Upload failed. Status: ${result.statusCode}, StatusText: ${result.statusText}, Body: ${result.bodyString}',
      );
    }
    return '';
  }
}
